package com.uu.safeguard.controller;

import com.alibaba.fastjson.JSONObject;
import com.uu.safeguard.aop.OperationLogAnnotation;
import com.uu.safeguard.common.Constant;
import com.uu.safeguard.entity.Project;
import com.uu.safeguard.result.Result;
import com.uu.safeguard.result.ResultFactory;
import com.uu.safeguard.service.PlatformService;
import com.uu.safeguard.service.ProjectService;
import com.uu.safeguard.service.StationService;
import com.uu.safeguard.utils.*;
import net.sf.json.JSONArray;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import redis.clients.jedis.Jedis;

import javax.annotation.Resource;
import javax.validation.constraints.NotEmpty;
import java.util.*;

@Validated
@RestController
@RequestMapping("/station")
public class StationController {

    private Logger logger = LoggerFactory.getLogger(StationController.class);

    @Resource
    private StationService stationService;

    @Resource
    private PlatformService platformService;

    @Resource
    private ProjectService projectService;
    /**
     * @Description: 一键解绑
     * @Param: [token, operatorMemberSn, params]
     **/
    @OperationLogAnnotation(operModul = "设备管理-设备解绑",operAction = "一键解绑",operDesc = "一键解绑")
    @PostMapping("/onekeyRemove")
    public Result onekeyRemove(@RequestHeader("token") String token, @RequestParam Map params){
        Long startStation = params.get("startStation")== null ? 0: Long.parseLong(params.get("startStation").toString());
        Long endStation = params.get("endStation")== null ? 0: Long.parseLong(params.get("endStation").toString());
        if (0 == startStation || 0 == endStation){
            return ResultFactory.buildFailResult("设备编号不能为空");
        }
        Long install =  endStation-startStation;
        if (50<=install||install<0){
            return ResultFactory.buildFailResult("最大解绑50台");
        }
        String sql = "";
        List parameter = new ArrayList();
        List<Map> list = new ArrayList();
        DbUtil db = new DbUtil();

        sql = "select count(sn) AS count from station where project_sn > 0 and sn >= cast(? as bigint) and sn <= cast(? as bigint) and name like '厂家-%' and operator_member_sn='180315151759'";
        parameter = new ArrayList();
        parameter.add(startStation);
        parameter.add(endStation);
        list = db.executeQueryBySql(sql, parameter);
        if(Integer.parseInt(list.get(0).get("count").toString()) != (install+1)){
            return ResultFactory.buildFailResult("此设备编号区间存在非测试设备，请重新输入");
        }

        for (long i = startStation; i < endStation+1; i++) {
            logger.info("厂家"+"_"+i);
            if (0<stationService.stationRemove(i+"")){
                //安装成功 什么也不操作
            }else{
                return ResultFactory.buildFailResult("解绑【"+i+"】时发生错误,设备非厂家测试设备");
            }
        }
        return ResultFactory.buildSuccessResult("解绑成功");
    }
    /**
     * @Description: 一键安装
     * @Param: [token, operatorMemberSn, params]
     **/
    @OperationLogAnnotation(operModul = "设备管理-设备信息修改",operAction = "一键安装",operDesc = "一键安装")
    @PostMapping("/onekeyInstall")
    public Result onekeyInstall(@RequestHeader("token") String token, @RequestParam Map params){
        String projectSn = params.get("projectSn").toString();
        if (StringUtils.isEmpty(projectSn)){
            return ResultFactory.buildFailResult("请输入小区编号");
        }
        if (StringUtils.isEmpty(params.get("socket_count").toString())){
            return ResultFactory.buildFailResult("请输入插座数量");
        }
        Long startStation = params.get("startStation")== null ? 0: Long.parseLong(params.get("startStation").toString());
        Long endStation = params.get("endStation")== null ? 0: Long.parseLong(params.get("endStation").toString());
        if (0 == startStation || 0 == endStation){
            return ResultFactory.buildFailResult("设备编号不能为空");
        }
        Long install =  endStation-startStation;
        if (50<=install||install<0){
            return ResultFactory.buildFailResult("最大安装50台");
        }
        Project project = projectService.queryById(Integer.parseInt(projectSn));
        if (null == project){
            return ResultFactory.buildFailResult("小区不存在");
        }
        //当前时间
        long nowTime = System.currentTimeMillis();
        logger.info("project:"+project.toString());
        String sql = "";
        List parameter = new ArrayList();
        List<Map> list = new ArrayList();
        DbUtil db = new DbUtil();

        sql = "select count(sn) AS count from station where project_sn > 0 and sn >= cast(? as bigint) and sn <= cast(? as bigint)";
        parameter = new ArrayList();
        parameter.add(startStation);
        parameter.add(endStation);
        list = db.executeQueryBySql(sql, parameter);
        if(Integer.parseInt(list.get(0).get("count").toString()) > 0){
            return ResultFactory.buildFailResult("此范围内的设备编号，存在已经安装的设备");
        }
        for (Long i = startStation; i < endStation+1; i++) {
            logger.info("厂家"+"_"+i);
            if (0<stationService.updateStationByCondition(project.getPlatformSn(), project.getOperatorMemberSn(), Integer.parseInt(projectSn), i + "", "厂家" + "-" + i)){
                //安装成功 改插座数量
                if(params.containsKey("socket_count") && StringUtils.isNotBlank(params.get("socket_count").toString()) && Integer.parseInt(params.get("socket_count").toString()) > 0){
                    Integer socketCount = Integer.parseInt(params.get("socket_count").toString());
                    if(socketCount >= 100){
                        return ResultFactory.buildFailResult("插座数量必须小于100");
                    }
                    Long finalI = i;
                    int count = db.table("socket").where(new ArrayList() {{
                        add(new ArrayList() {{
                            add("station_sn");
                            add("=");
                            add(finalI);
                        }});
                    }}).count("sn");

                    //如果增加插座
                    if(socketCount > count){
                        List insertAllData = new ArrayList();
                        for (int j = count + 1; j <= socketCount; j++) {
                            Map socketMap = new HashMap();
                            socketMap.put("sn",i +""+ j);
                            socketMap.put("station_sn",i);
                            socketMap.put("socket_number",j);
                            socketMap.put("state",1);
                            socketMap.put("create_time",nowTime);
                            insertAllData.add(socketMap);
                        }
                        logger.info("insertAllData:"+insertAllData);
                        db.table("socket").insertAll(insertAllData);
                    }
                }
            }else{
                return ResultFactory.buildFailResult("分配【"+i+"】时发生错误，设备非本平台或未录入");
            }
        }
        return ResultFactory.buildSuccessResult("安装成功");
    }

    //开启插座
    @PostMapping("startSocket")
    @OperationLogAnnotation(operModul = "设备-开启插座",operAction = "开启",operDesc = "开启插座")
    public Result startSocket(@RequestHeader("token")String token, String sn){
        if(sn == null || sn.equals("")){
            return ResultFactory.buildFailResult("插座信息有误");
        }
        DbUtil db = new DbUtil();
        //String memberSn = JwtUtil.getUserId(token);
        LinkedHashMap<String, String> operatorBySocketSn = stationService.findOperatorBySocketSn(sn);
        if (null == operatorBySocketSn){
            return ResultFactory.buildFailResult("设备无运营商");
        }
        //设备运营商开启插座
        String memberSn = operatorBySocketSn.get("operator_member_sn");
        Map member = db.table("member").where(new ArrayList(){{
            add(new ArrayList(){{
                add("sn");
                add("=");
                add(memberSn);
            }});
        }}).find("sn,type,one_charge_minuts,balance,project_sn, operator_member_sn, cancel_noload_check");

        if(member.size() == 0){
            return ResultFactory.buildFailResult("无权操作");
        }

        String sql = "select project.is_burst_power_close,project.burst_power,project.project_charging_price,project.project_charging_degree_money,project.float_charge_power,project.float_charge_minuts,project.starting_price,project.realtime_type,project.start_charging_minuts,project.charging_mode,project.is_safe_charge,project.is_free,project.month_card_max_power,socket.sn,socket_number,socket.station_sn,station.project_sn as project_sn,station.is_online,station.operator_member_sn as station_operator_member_sn,station.type as station_type,station.tcp_address,platform.safe_money,platform.is_safe_charge as platform_is_safe_charge from socket left join station on station.sn = socket.station_sn left join project on project.sn = station.project_sn left join platform on platform.sn = station.platform_sn where socket.sn = ?";
        List parameter = new ArrayList<Object>(){{
            add(sn);
        }};
        List list = db.executeQueryBySql(sql, parameter);
        if(list.size() == 0){
            return ResultFactory.buildFailResult("插座信息有误");
        }
        Map socket = (Map) list.get(0);




        //当前时间
        long create_time = System.currentTimeMillis();
        //起步价
        double starting_price = 0.0;
        //是否安心充电
        int is_safe_charge = 0;
        //安心充电金额
        String safe_money = "0";
        //固定金额
        String fix_money = "0";
        //最大功率
        int max_power_limit = -1;
        //剩余时长
        long remain_millisecond = Integer.parseInt(member.get("one_charge_minuts").toString()) * 60 * 1000;
        //浮充时长
        long float_charge_millisecond = Integer.parseInt(socket.get("float_charge_minuts").toString()) * 60 * 1000;
        //是否免费
        String is_free = "1";
        //是否漫游
        String is_roaming = "0";
        //是否取消空载检测
        String cancel_noload_check = member.get("cancel_noload_check").toString();
        //充电类型 1实时模式 2固定模式  3月卡
        String charging_mode = "1";
        //开始计费时间
        String start_charging_minuts = "0";
        //月卡配置
        JSONObject monthCardJson = new JSONObject();

        //判断两次充电都是空载结束，且没有计费 则本次取消空载检测
        if(cancel_noload_check.equals("0")){
            List chargeLogs = db.table("charge_log").where(new ArrayList() {{
                add(new ArrayList() {{
                    add("member_sn");
                    add("=");
                    add(memberSn);
                }});
            }}).order("id desc").limit(2).select("end_reason,degree");
            int cancel_noload_check_judge = 0;
            for (int i = 0; i < chargeLogs.size(); i++) {
                Map o = (Map) chargeLogs.get(i);
                if(o.get("end_reason").equals("-41") && Double.parseDouble(o.get("degree").toString()) < 0.01){
                    cancel_noload_check_judge ++;
                }else{
                    cancel_noload_check_judge = 0;
                }
            }
            if(cancel_noload_check_judge == 2){
                cancel_noload_check = "1";
            }
        }

        //判断是否漫游
        if(!socket.get("station_operator_member_sn").equals(member.get("operator_member_sn"))){
            is_roaming = "1";
        }

        if(socket.get("project_charging_price").toString().equals("") || socket.get("project_charging_price").toString().equals("[]") && (socket.get("project_charging_degree_money").toString().equals("") || socket.get("project_charging_degree_money").toString().equals("[]"))){
            return ResultFactory.buildFailResult("计费方式设置有误，请联系运营商");
        }

        //查询功率阶梯计费数据
        List project_charging_price_list = com.alibaba.fastjson.JSONArray.parseArray(socket.get("project_charging_price").toString());
        //查询电度分时电价
        List project_charging_degree_money_list = com.alibaba.fastjson.JSONArray.parseArray(socket.get("project_charging_degree_money").toString());

        if(project_charging_price_list.size() == 0 && project_charging_degree_money_list.size() == 0){
            return ResultFactory.buildFailResult("计费方式设置有误，请联系运营商");
        }
        for (int i = 0; i < project_charging_price_list.size(); i++) {
            Map o = (Map) project_charging_price_list.get(i);
            double hour_price = 1 / Double.parseDouble(o.get("money_hours").toString());
            o.put("hour_price", Double.parseDouble(CommonUtil.formatMoney(hour_price,2)));
            o.put("money_hours",Double.parseDouble(o.get("money_hours").toString()));
            o.put("start_power",Integer.parseInt(o.get("start_power").toString()));
            o.put("end_power",Integer.parseInt(o.get("end_power").toString()));
            project_charging_price_list.set(i,o);

            //最大功率
            if(Double.parseDouble(o.get("end_power").toString()) > max_power_limit){
                max_power_limit = (int)Math.ceil(Double.parseDouble(o.get("end_power").toString()));
            }
        }

        for (int i = 0; i < project_charging_degree_money_list.size(); i++) {
            Map o = (Map) project_charging_degree_money_list.get(i);
            o.put("start_hour",Integer.parseInt(o.get("start_hour").toString()));
            o.put("end_hour",Integer.parseInt(o.get("end_hour").toString()));
            o.put("start_minute",Integer.parseInt(o.get("start_minute").toString()));
            o.put("end_minute",Integer.parseInt(o.get("end_minute").toString()));
            o.put("service_money",Double.parseDouble(o.get("service_money").toString()));
            o.put("degree_money",Double.parseDouble(o.get("degree_money").toString()));
            project_charging_degree_money_list.set(i,o);
            max_power_limit = -1;
        }


        String redisKey = sn;
        HashMap redisMap = new HashMap() {{
            put("sn", sn + "");
            put("station_sn", socket.get("station_sn") + "");
            put("socket_number", socket.get("socket_number") + "");
            put("member_sn",memberSn + "");
            put("member_type",member.get("type") + "");
            put("cmd","1");
            put("state","0");
            put("money_total","0");
            put("power_value","0");
            put("cmd_time",create_time + "");
        }};
        redisMap.put("month_card",monthCardJson.toString());
        redisMap.put("charging_mode",charging_mode+ "");
        redisMap.put("remain_millisecond",remain_millisecond + "");
        redisMap.put("is_free",is_free+ "");
        redisMap.put("cancel_noload_check",cancel_noload_check+ ""); //是否取消空载检测
        redisMap.put("is_roaming",is_roaming+ "");
        redisMap.put("max_power_limit",max_power_limit+ "");
        redisMap.put("start_charging_minuts",start_charging_minuts+ "");
        redisMap.put("is_safe_charge",is_safe_charge + "");
        redisMap.put("safe_money",safe_money+ "");
        redisMap.put("fix_money",fix_money + "");
        redisMap.put("realtime_type",socket.get("realtime_type") + ""); //实时计费模式，1实时，2只升不降
        redisMap.put("starting_price",starting_price + ""); //起步价
        redisMap.put("project_charge_price_config",JSONArray.fromObject(project_charging_price_list).toString());
        redisMap.put("project_charge_degree_money_config",JSONArray.fromObject(project_charging_degree_money_list).toString());
        redisMap.put("float_charge_millisecond",float_charge_millisecond + "");
        redisMap.put("float_charge_power",socket.get("float_charge_power") + ""); //浮充功率
        redisMap.put("is_burst_power_close",socket.get("is_burst_power_close") + ""); //是否开启暴增功率关闭
        redisMap.put("burst_power",socket.get("burst_power") + ""); //暴增功率
        Jedis jedis = JedisUtil.getJedis();
        jedis.select(0); //存插座信息
        //查询缓存中是否存在
        if(jedis.exists(redisKey)){
            String state = jedis.hget(redisKey, "state");
            if(state.equals("2")){
                JedisUtil.close(jedis);
                return ResultFactory.buildFailResult("此插座正在使用");
            }
        }

        String tcpAddress = socket.get("tcp_address").toString();
        //判断是否正在执行开关
        jedis.select(2); //存开关信息
        if(jedis.exists(tcpAddress + "_cmd")){
            JedisUtil.close(jedis);
            return ResultFactory.buildFailResult("此插座正在开启或关闭，请稍后再试");
        }
        jedis.select(0); //存插座信息
        String hmset = jedis.hmset(redisKey, redisMap);
        if(hmset.equals("OK")){
            JSONObject cmdJson = new JSONObject();
            cmdJson.put("sn", sn + "");
            cmdJson.put("cmd" , "1");
            cmdJson.put("cmd_time",create_time + "");
            jedis.select(2); //存其他

            jedis.lpush(tcpAddress + "_cmd",cmdJson.toString());
        }
        JedisUtil.close(jedis);

        return ResultFactory.buildSuccessResult(new JSONObject());
    }


    //结束充电
    @PostMapping("endSocket")
    @OperationLogAnnotation(operModul = "设备-关闭插座",operAction = "关闭",operDesc = "关闭插座")
    public Result endSocket(@RequestHeader("token")String token, String sn){
        DbUtil db = new DbUtil();
        long create_time = System.currentTimeMillis();
        String redisKey = sn;

        Jedis jedis = JedisUtil.getJedis();
        jedis.select(0);
        if(!jedis.exists(redisKey)){
            JedisUtil.close(jedis);
            return ResultFactory.buildFailResult("此插座未开启，不可停止");
        }


        String sql = "select station.operator_member_sn as station_operation_member_sn,station_sn,station.last_communicate_time,station.type as station_type,station.tcp_address,station.platform_sn from socket left join station on station.sn = socket.station_sn  where socket.sn = ?";
        List parameter = new ArrayList<Object>(){{
            add(sn);
        }};
        List list = db.executeQueryBySql(sql, parameter);
        if(list.size() == 0){
            JedisUtil.close(jedis);
            return ResultFactory.buildFailResult("插座信息有误");
        }
        Map socketInfo = (Map) list.get(0);

        String platform_sn = socketInfo.get("platform_sn").toString();
        String tcpAddress = socketInfo.get("tcp_address").toString();
        //判断是否正在执行开关
        jedis.select(2); //存开关信息
        if(jedis.exists(tcpAddress + "_cmd")){
            JedisUtil.close(jedis);
            return ResultFactory.buildFailResult("此插座正在开启或关闭，请稍后再试");
        }
        jedis.select(0);

        String last_communicate_time = socketInfo.get("last_communicate_time").toString();
        if(create_time - Long.parseLong(last_communicate_time) > Constant.STATION_TIMOUT){
            /*net.sf.json.JSONObject socketCmdStopmoneyJson = new net.sf.json.JSONObject();
            socketCmdStopmoneyJson.put("sn", sn + "");
            socketCmdStopmoneyJson.put("end_reason", "21");
            jedis.select(2);
            jedis.lpush("socket_cmd_stopmoney",socketCmdStopmoneyJson.toString());
            JedisUtil.close(jedis);
            return ResultFactory.buildSuccessResult(new net.sf.json.JSONObject());*/
            jedis.hset(redisKey,"end_reason","21");
            JedisUtil.close(jedis);
            SocketUtil.end_charge(sn,platform_sn);
            return ResultFactory.buildSuccessResult(new net.sf.json.JSONObject());
        }

        jedis.hset(redisKey, "end_reason", "24"); //写入关闭原因

        JSONObject cmdJson = new JSONObject();
        cmdJson.put("sn", sn + "");
        cmdJson.put("cmd" , "-1");
        cmdJson.put("cmd_time",create_time + "");

        jedis.select(2);

        jedis.lpush(tcpAddress + "_cmd",cmdJson.toString());

        /*if(socketInfo.get("station_type").toString().equals("5")){
            jedis.lpush("socket_cmd_bl",cmdJson.toString());
        }else if(socketInfo.get("station_sn").toString().length() > 8){
            jedis.lpush("socket_cmd_new",cmdJson.toString());
        }else if(socketInfo.get("station_sn").toString().length() == 8 && socketInfo.get("station_sn").toString().substring(0,1).equals("1")){
            jedis.lpush("socket_cmd_car",cmdJson.toString());
        }else{
            jedis.lpush("socket_cmd",cmdJson.toString());
        }*/

        JedisUtil.close(jedis);

        return ResultFactory.buildSuccessResult(new JSONObject());
    }
    /**
     * @Description: 某小区在线设备
     * @Param: [token, operatorMemberSn]
     * @Author: cmt
     **/
    @PostMapping("/projectOnline")
    public Result projectOnline(@RequestHeader("token")String token,@RequestHeader("operatorMemberSn")@NotEmpty(message="operatorMemberSn 不能为空")String operatorMemberSn){
        List<Map<String, String>> projectOnline = stationService.findProjectStationOnline(operatorMemberSn);
        return ResultFactory.buildSuccessResult(projectOnline);
    }

    /**
     * @Description: 运营商某小区设备监控 小区详情
     * @Param: [token, operatorMemberSn]
     * @Author: cmt
     **/
    @PostMapping("/projectDetails")
    public Result projectDetails(@RequestHeader("token")String token,@RequestHeader("operatorMemberSn")@NotEmpty(message="operatorMemberSn 不能为空")String operatorMemberSn){
        List<Map<String, String>> projectDetails = stationService.findOperatorProjectDetails(operatorMemberSn);
        return ResultFactory.buildSuccessResult(projectDetails);
    }

    /**
     * @Description: 某运营商设备总台数及在线、离线数量
     * @Param: [token, operatorMemberSn]
     * @Author: cmt
     **/
    @PostMapping("/operatorAll")
    public Result operatorAll(@RequestHeader("token")String token, @RequestHeader("operatorMemberSn")@NotEmpty(message="operatorMemberSn 不能为空")String operatorMemberSn){
        Map<String, String> operatorAllStation = stationService.findOperatorAllStation(operatorMemberSn);
        return ResultFactory.buildSuccessResult(operatorAllStation);
    }

    /**
     * @Description: 设备列表
     * @Param: [token, operatorMemberSn, projectSn, isOnline, limit, page]
     * @Return: com.uu.chargeoperator.result.Result
     * @Author: zdf
     **/
    @PostMapping("list")
    public Result list(@RequestHeader("token") String token, String keywords, Integer projectSn,Integer isOnline, Integer limit, Integer page){
        //当前时间
        long nowTime = System.currentTimeMillis();
        if(limit == null ){
            limit = 100;
        }
        if(page == null ){
            page = 1;
        }
        int offset = (page - 1) * limit;
        List list = new ArrayList();
        int count = 0;
        int socket_count = 0;


        String WhereSql = " where station.project_sn > 0  "; //已安装设备
        WhereSql += " ";
        if(projectSn != null){
            WhereSql += " and station.project_sn = ? ";
        }
        if(keywords != null && StringUtils.isNotBlank(keywords)){
            String[] station_sn_arr = keywords.split("-");
            if(station_sn_arr.length == 2){
                WhereSql += " and ( station.sn >= ? and  station.sn <= ? )";
            }else{
                WhereSql += " and ( station.sn = ? or station.name like ?  or project.name like ? )";
            }

        }

        DbUtil db = new DbUtil();

        String tempTableSql = "select station.version,operator.name as operator_name,project.sn as project_sn,project.name as project_name,station.operator_member_sn,station.install_time,station.create_time,station.name as station_name,gprs,station.sn as station_sn,last_communicate_time,socket_count,station.type,(select count(sn) from socket where socket.station_sn = station.sn and socket.state = 2) as used_count,(select count(sn) from socket where socket.station_sn = station.sn and socket.state = 1) as unused_count,(case when station.last_communicate_time > " + (nowTime - Constant.STATION_TIMOUT) + " then 1 else 0 end) as is_online from station left join project on project.sn = station.project_sn left join operator on operator.member_sn = station.operator_member_sn " + WhereSql;

        String sql = "select * from ( " + tempTableSql + " ) as temp_table where 1 = 1 ";

        List parameter = new ArrayList();

        if(projectSn != null){
            parameter.add(projectSn);
        }
        if(keywords != null && StringUtils.isNotBlank(keywords)){
            String[] station_sn_arr = keywords.split("-");
            if(station_sn_arr.length == 2){
                parameter.add(station_sn_arr[0]);
                parameter.add(station_sn_arr[1]);
            }else{
                parameter.add(keywords);
                parameter.add("%" + keywords + "%");
                parameter.add("%" + keywords + "%");
            }

        }

        if(isOnline != null && (isOnline == 0 || isOnline == 1)){
            sql += " and is_online = ? ";
            parameter.add(isOnline);
        }

        sql += " order by station.sn asc OFFSET ? ROWS FETCH NEXT ?  ROWS ONLY";
        parameter.add(offset);
        parameter.add(limit);
        list = db.executeQueryBySql(sql, parameter);


        for (int i = 0; i < list.size(); i++) {
            Map station = (Map) list.get(i);
            Double usedRate = (Double.parseDouble(station.get("used_count").toString()) / Double.parseDouble(station.get("socket_count").toString()));
            station.put("used_rate",usedRate);
            station.put("used_rate_percentage",Math.ceil(usedRate * 100 * 100) / 100);
            station.put("type_text",Constant.STATION_TYPE_MAP.get(station.get("type").toString()));
            station.put("_install_time", CommonUtil.stampToDate(Long.parseLong(station.get("install_time").toString()),"yyyy-MM-dd HH:mm"));

            station.put("_offline_time", CommonUtil.stampToDate(Long.parseLong(station.get("last_communicate_time").toString()),"yyyy-MM-dd HH:mm"));
            station.put("offline_duration",CommonUtil.stampToDuration(nowTime - Long.parseLong(station.get("last_communicate_time").toString()) ));
            if(Long.parseLong(station.get("last_communicate_time").toString()) == 0){
                station.put("_offline_time", CommonUtil.stampToDate(Long.parseLong(station.get("install_time").toString()),"yyyy-MM-dd HH:mm"));
                station.put("offline_duration",CommonUtil.stampToDuration(nowTime - Long.parseLong(station.get("install_time").toString()) ));
            }

            list.set(i,station);
        }

        String count_sql = "select count(*) as count,(case when sum(socket_count) is null then 0 else sum(socket_count) end) as socket_total_count from ( " + tempTableSql + " ) as temp_table where 1 = 1 ";
        List count_parameter = new ArrayList();
        if(projectSn != null){
            count_parameter.add(projectSn);
        }
        if(keywords != null && StringUtils.isNotBlank(keywords)){
            String[] station_sn_arr = keywords.split("-");
            if(station_sn_arr.length == 2){
                count_parameter.add(station_sn_arr[0]);
                count_parameter.add(station_sn_arr[1]);
            }else{
                count_parameter.add(keywords);
                count_parameter.add("%" + keywords + "%");
                count_parameter.add("%" + keywords + "%");
            }

        }
        if(isOnline != null && (isOnline == 0 || isOnline == 1)){
            count_sql += " and is_online = ? ";
            count_parameter.add(isOnline);
        }
        List<Map> count_list = db.executeQueryBySql(count_sql, count_parameter);


        if(count_list.size() > 0){
            count = (int)count_list.get(0).get("count");
            socket_count = (int)count_list.get(0).get("socket_total_count");
        }

        Map data = new HashMap();
        data.put("list",list);
        data.put("count",count);
        data.put("socket_count",socket_count);
        return ResultFactory.buildSuccessResult(data);
    }

    /**
     * @Description: 电站详情
     * @Param: [token, sn]
     **/
    @PostMapping("getStationNodeBlQrcode")
    public Result getStationNodeBlQrcode(@RequestHeader("token") String token, String sn){
        if(sn == null || StringUtils.isBlank(sn)){
            return ResultFactory.buildFailResult("编号不能为空");
        }
        if(sn.substring(0,3).equals("NTB")) {
            sn = sn.substring(3, 11);
        }
        String SN = sn;
        DbUtil db = new DbUtil();
        Map stationNodeBlQrcode = db.table("station_node_bl_qrcode").where(new ArrayList() {{
            add(new ArrayList() {{
                add("left_sn");
                add("=");
                add(SN);
            }});
            add(new ArrayList() {{
                add("right_sn");
                add("=");
                add(SN);
                add("or");
            }});
        }}).find("node_mac");
        if(null == stationNodeBlQrcode || stationNodeBlQrcode.size() == 0){
            return ResultFactory.buildFailResult("参数有误");
        }
        return ResultFactory.buildSuccessResult(stationNodeBlQrcode);
    }

    //详情
    @PostMapping("detail")
    public Result detail(@RequestHeader("token") String token, String sn){
        if(sn == null || StringUtils.isBlank(sn)){
            return ResultFactory.buildFailResult("设备编号不能为空");
        }
        DbUtil db = new DbUtil();
        List where = new ArrayList();
        where.add(new ArrayList(){{
            add("station.sn");
            add("=");
            add(sn);
        }});

        Map detail = db.table("station left join project on project.sn = station.project_sn").where(where).find("station.*,project.name as project_name");

        if(detail.size() == 0){
            return ResultFactory.buildFailResult("信息不存在");
        }

        Map platform = platformService.detail(detail.get("platform_sn").toString());
        detail.put("_image_1",platform.get("operator_url").toString() + detail.get("image_1").toString());
        detail.put("_image_2",platform.get("operator_url").toString() + detail.get("image_2").toString());
        detail.put("_image_3",platform.get("operator_url").toString() + detail.get("image_3").toString());

        //如果是柏来设备
        if(detail.get("type").toString().equals("5")){
            //获取节点信息
            String nodeBlSql = "select node_mac,node_id,socket_count from  station_node_bl where station_sn = ? group by node_mac,node_id,socket_count order by cast(node_id as int) asc";
            List nodeBlParameter = new ArrayList();
            nodeBlParameter.add(sn);
            List nodeBlList = db.executeQueryBySql(nodeBlSql, nodeBlParameter);
            JSONArray node_bl = JSONArray.fromObject(nodeBlList);

            detail.put("node_bl",node_bl.toString());
        }


        return ResultFactory.buildSuccessResult(detail);
    }

    //detailForsocket
    @PostMapping("detailForsocket")
    public Result detailForsocket(@RequestHeader("token") String token,String sn){
        if(sn == null || StringUtils.isBlank(sn)){
            return ResultFactory.buildFailResult("设备编号不能为空");
        }

        //当前时间
        long nowTime = System.currentTimeMillis();
        DbUtil db = new DbUtil();

        String tempTableSql = "select operator.name as operator_name,platform.platform_name,project.sn as project_sn,project.name as project_name,station.platform_sn,station.image_1,station.image_2,station.image_3,station.operator_member_sn,station.install_time,station.create_time,station.name as station_name,gprs,station.sn as station_sn,last_communicate_time,socket_count,station.type,(select count(sn) from socket where socket.station_sn = station.sn and socket.state = 2) as used_count,(select count(sn) from socket where socket.station_sn = station.sn and socket.state = 1) as unused_count,(case when station.last_communicate_time > " + (nowTime - Constant.STATION_TIMOUT) + " then 1 else 0 end) as is_online from station left join project on project.sn = station.project_sn left join platform on platform.sn=station.platform_sn left join operator on station.operator_member_sn= operator.member_sn where  station.sn = ?" ;

        String sql = "select * from ( " + tempTableSql + " ) as temp_table where 1 = 1 ";
        List parameter = new ArrayList();
        parameter.add(sn);

        List list = db.executeQueryBySql(sql, parameter);

        if (list.size() == 0){
            return ResultFactory.buildFailResult("信息不存在");
        }


        Map station = (Map) list.get(0);

        station.put("type_text",Constant.STATION_TYPE_MAP.get(station.get("type").toString()));
        station.put("_install_time", CommonUtil.stampToDate(Long.parseLong(station.get("install_time").toString()),"yyyy-MM-dd HH:mm"));
        station.put("_offline_time", CommonUtil.stampToDate(Long.parseLong(station.get("last_communicate_time").toString()),"yyyy-MM-dd HH:mm"));
        station.put("offline_duration",CommonUtil.stampToDuration(nowTime - Long.parseLong(station.get("last_communicate_time").toString()) ));
        if(Long.parseLong(station.get("last_communicate_time").toString()) == 0){
            station.put("_offline_time", CommonUtil.stampToDate(Long.parseLong(station.get("install_time").toString()) ,"yyyy-MM-dd HH:mm"));
            station.put("offline_duration",CommonUtil.stampToDuration(nowTime - Long.parseLong(station.get("install_time").toString()) ));
        }
        station.put("install_days",Math.round((nowTime - Long.parseLong(station.get("install_time").toString()) ) / 86400000.0)); //运行天数

        //照片
        Map platform = platformService.detail(station.get("platform_sn").toString());
        station.put("_image_1",platform.get("operator_url").toString() + station.get("image_1").toString());
        station.put("_image_2",platform.get("operator_url").toString() + station.get("image_2").toString());
        station.put("_image_3",platform.get("operator_url").toString() + station.get("image_3").toString());


        //插座列表
        String list_sql = "SELECT socket.sn as socket_sn,socket.socket_number,socket.state,member.sn as member_sn,member.nickname,member.avatar,member.type as member_type from socket left join member on member.sn = socket.member_sn where socket.station_sn = ? order by socket.socket_number asc";
        List socketParameter = new ArrayList<Object>(){{
            add(sn);
        }};
        List<Map> socketList = db.executeQueryBySql(list_sql,socketParameter);

        Jedis jedis = JedisUtil.getJedis();
        jedis.select(0);
        for (int i = 0; i < socketList.size(); i++) {
            Map o = (Map) socketList.get(i);
            //查询缓存中是否存在
            String redisKey = o.get("socket_sn").toString();
            if(jedis.exists(redisKey)){
                Map<String, String> socketInfo = jedis.hgetAll(redisKey);
                if(!socketInfo.containsKey("state")){
                    continue;
                }
                if(socketInfo.get("state").equals("0")){
                    continue;
                }
                long charging_seconds = (System.currentTimeMillis() - Long.parseLong(socketInfo.get("start_time")) ) / 1000;
                int hour = (int)Math.floor(charging_seconds / 3600);
                int minute = (int)Math.floor((charging_seconds - (hour * 3600))  / 60);
                int second = (int)Math.floor((charging_seconds - (hour * 3600) - (minute * 60)) % 60);
                String hourStr = String.format("%02d", hour);
                String minuteStr = String.format("%02d", minute);
                String secondStr = String.format("%02d", second);
                o.put("charge_time",hourStr + ":" + minuteStr + ":" + secondStr);
                o.put("_charge_hour",hourStr);
                o.put("_charge_minute",minuteStr);
                o.put("_charge_second",secondStr);

                o.put("money_total", CommonUtil.formatMoney(Double.parseDouble(socketInfo.get("money_total")),2));
                o.put("power_value", socketInfo.get("power_value"));
                o.put("charge_log_id", socketInfo.get("charge_log_id"));
                o.put("charging_mode", socketInfo.get("charging_mode"));
            }else{
                o.put("state",1);
            }

            socketList.set(i,o);

        }
        JedisUtil.close(jedis);

        station.put("socket_list",socketList);

        return ResultFactory.buildSuccessResult(station);
    }

    //插座状态
    @PostMapping("socketState")
    public Result socketState(@RequestHeader("token")String token,String sn){
        if(sn == null || sn.equals("")){
            return ResultFactory.buildFailResult("插座信息有误");
        }

        Map<String, String> socket = new HashMap<>();
        String redisKey = sn;
        Jedis jedis = JedisUtil.getJedis();
        jedis.select(0); //存插座信息
        //查询缓存中是否存在
        if(jedis.exists(redisKey)){
            socket = jedis.hgetAll(redisKey);
        }else{
            DbUtil db = new DbUtil();
            socket = db.table("socket").where(new ArrayList(){{
                add(new ArrayList(){{
                    add("sn");
                    add("=");
                    add(sn);
                }});
            }}).find("state,sn");
        }
        JedisUtil.close(jedis);

        JSONObject resultData = new JSONObject();
        resultData.put("state",socket.get("state"));
        resultData.put("sn",socket.get("sn"));
        return ResultFactory.buildSuccessResult(resultData);
    }

}
